pull in latest upstream#2
Open
TtheBC01 wants to merge 799 commits into
Open
Conversation
The /api/x402/demo endpoint did not help the isitagentready.com scanner detect x402 support. Removing dead code.
* docs: add builder_code.md spec * support services array
* spec + sdk * add auto recover and topUp; add filestorage * add session manager * fix nonce reset * add cooperativeWithdraw to spec/contract * add cooperative withdraw to sdk * update sdk to match spec v1.2 * change to auto-generated getters * improve server devx * improve client devx * added concurrent request example * minor fixes * add cas * add streaming example * rename files to batched* * updated scheme name deferred -> batched * update to new contracts * align paymentresponse.extra for all payloads * fix recovery after refund * fix withdraw -> refund flag * fix channel manager * rename to batch-settlement * align with cloudflare specs * remove claim/refund without sign * add tx sim * improve specs * specs ready * add unit/integration tests * fix tests * improve typing, remove dead code * add readmes * add e2e tests * fix fileStorage * increase depositMultiplier for streaming * refund without paid request * refactor convertToTokenAmount * refactor scheme * fix recovery for refund flow * refactor client scheme * rename session -> channel * remove chargedCumulativeAmount from deposit payload * scheme hook adapters * add enrichSettlementPayload/enrichSettlementResponse hooks * move batch-settlement scheme to scheme hook adapters and enrichSettlementResponse * refactor refund and other payloads * add client hook adapters * align payment-response shapes * move corrective 402 info from errorDetails to requirements.extra.channelState * fix corrective deposit flow * update to latest deployment and change channelId computation to EIP-712 * add hook to handle route handler failures * add atomic channel update and request context primitives * guard channels with pending reservations * fix concurrent claim/settle * skip facilitator and verify locally if onchain state fresh * add redis storage * add fullstack next example with redis and fix settlementOverride for next package * align payment-response for all payloads * add permit2 support and fix extra enrichment for nested objects * fix DEPOSIT_WITNESS_TYPE_STRING * test client state-loss recovery scenario in e2e * fix recovery for axios * improve channel manager * update client deposit policy * clean up examples * add to testnet facilitator * update READMEs * for the culture * add changesets * update to latest deployment * align error codes * remove receiverAuthorizer fallback
* feat: added cdk to example * feat: pin x402 package versions * feat: updated pin to float patch
* batch-settlement on EVM * update refund flow and payloads * move corrective 402 info from errorDetails to requirements.extra.ChannelState and compute channelID from EIP712Hash * align payment-response for all payloads * post audit updates * add deposit collector addresses * update error codes
* docs: add repo move note to README (#40) * add service metadata on resource to all 3 SDKs * lint * changelog * review: harden iconUrl validators + tighten signatures * review: constrain serviceName/tags to printable ASCII * add checks to harden iconurl + tag/name validators * update v2 spec + python lint * python format --------- Co-authored-by: Ash <105402607+Must-be-Ash@users.noreply.github.com>
Generated-By: mintlify-agent Mintlify-Source: dashboard-editor Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
* Update docs/sdk-features.md Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/sdk-features.md Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/core-concepts/network-and-token-support.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/core-concepts/network-and-token-support.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/core-concepts/network-and-token-support.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/core-concepts/network-and-token-support.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/core-concepts/network-and-token-support.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor --------- Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
…ecoin (Permit2 + EIP-2612) (#2038) * feat(evm): add Radius Network and Radius Testnet default stablecoin (Permit2 + EIP-2612) Add SBC as the default stablecoin for Radius Network (eip155:723487) and Radius Testnet (eip155:72344) across Go, TypeScript, and Python SDKs. SBC does not support EIP-3009, so Permit2 is the required transfer method. SBC does support EIP-2612 permit() for gasless approval. * docs: add Radius default-stablecoin entries to user-facing docs * chore(paywall): update generated Radius decimals
* feat: add batch-settlement implementation to Go SDK * feat: add batch-settlement examples for go sdk * feat: updated typescript examples to match go examples * feat: add e2e testing for batch-settlement in go * Batch-settlement: go-ts parity (#2227) * fix PendingRequest and refund cleanup * fix lint * remove duplicate payer info from storage * fix PAYMENT-RESPONSE field ordering * clean up comments * consolidate ProcessSettlementWithExtensions into ProcessSettlement --------- Co-authored-by: phdargen <p.dargent@cern.ch>
* feat: add TVM exact-payment mechanism to Python SDK - add TVM exact client, server, and facilitator implementations - add TVM signers, codecs, provider, and settlement helpers - add unit and integration coverage for TON testnet/mainnet flows - add Python examples and e2e wiring for TVM * Enable TVM exact flows in Python e2e and tighten facilitator validation Add TVM support to the Python e2e clients and servers, switch TVM usage to direct `ExactTvm*Scheme` registration after removing the old register helpers, and refresh docs/examples for testnet setup. Also reject exact TVM settlements with excessively large attached TON amounts and cover the new validation with tests. * fix: clarify minimum balance of the facilitator * refactor(tvm): release settlement cache entry on confirmed settlement On-chain seqno advances after a successful relay, so any retry of the same settlement BOC will fail at the W5 contract's seqno check regardless of the dedup reservation. Drop the entry as soon as the confirmation worker records success, so the invariant becomes "every is_duplicate=False is paired with a release" and TTL pruning is left as a crash safety-net only. * feat(tvm): add TonAPI provider support * feat(tvm): update e2e tests to make them compatible with new providers * fix(tvm): update timeouts * fix(tvm): increase http client timeout * fix(tvm): align unit tests * revert(e2e): remove .env-local config load Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
#2242) Tightens the viem floor in every package.json that lists viem (41 refs across 40 files), refreshes all three lockfiles so every direct viem resolution reads 2.48.11, and regenerates the paywall bundled templates so the EVM/SVM/AVM bundles match the new viem chain database. ## Why floor-tightening matters PR #2013 bumped lockfiles to 2.47.14, but later PRs (#2061, #2197, ...) added sub-packages with ^2.39.x / ^2.43.x floors. pnpm re-resolved on subsequent installs and the solver picked the lowest acceptable version across constraints. ^-ranges with low floors do NOT preserve a bump -- lockfile refreshes erode the floor. This PR fixes that incomplete tightening from #2013 by raising every floor to ^2.48.11. The same regression will recur if any future PR adds a viem-using sub-package with a lower floor. Gate criterion: new packages must use ^2.48.11 (or tighter) for viem. ## Acceptance verification - pnpm install --frozen-lockfile clean across typescript/, examples/typescript/, and e2e/. - pnpm format:check, lint:check, build, test green for typescript/. - pnpm format:check, lint:check green for examples/typescript/. - All direct viem resolutions read 2.48.11 in all three workspaces. - Paywall bundled templates regenerated via pnpm --filter @x402/paywall run build:paywall.
* docs(facilitators): add Solvador to facilitators list * docs(facilitators:solvador): add NEAR support
…t error (#2721) * fix(python/flask): return 500 (and log) on unexpected settlement error * chore(changelog): name flask settlement fragment by PR number * fix(python/flask): surface unexpected settlement error as 402 + PAYMENT-RESPONSE (mirror #2622) * fix(python/flask): use canonical unexpected_settle_error reason (parity with #2622) * style(python): apply ruff format to test_flask.py * chore(python): restore uv.lock to main (no dependency changes in this PR) * chore(python): leave uv.lock untouched (no dependency changes)
* verify aptos sign * verify aptos sign
* feat(xrpl): add exact scheme TypeScript reference implementation Implements specs/schemes/exact/scheme_exact_xrpl.md as @x402/xrpl with client, resource-server, and facilitator schemes for payer-signed XRPL Payment transactions: - sequence and ticketSequence asset transfer methods with the spec's resolution order, per-method verification (current account Sequence, ticket availability), and a createTickets utility - extra.areFeesSponsored=false advertised via facilitator getExtra and enforced in envelope verification - offline signature validation, NetworkID binding, InvoiceID invoice binding (Memos rejected), Delegate/Paths/DeliverMin/partial-payment rejection, fee caps, LastLedgerSequence expiry policy, and simulation (signature fields stripped: the XRPL simulate API only accepts unsigned transactions) - settlement re-verifies, submits, and requires validated tesSUCCESS - XRP drops and issued-currency decimal value amounts compared with exact decimal arithmetic (no extra.decimals field) The server scheme keeps enhancePaymentRequirements deterministic (requirements are rebuilt per request), so invoice binding activates only when the resource configuration provides extra.invoiceId. Adds unit and integration tests, publish workflows, release-script and changeset fixed-group wiring, and the root test:integration filter. * feat(e2e): wire XRPL into the e2e harness and participants Adds the xrpl protocol family to the harness networks/types/env plumbing, registers @x402/xrpl in the axios and fetch clients, the express/fastify/hono/next servers (GET /exact/xrpl routes priced in XRP drops), the TypeScript facilitator (keyless: the payer signs and pays XRPL fees), and the mock facilitator supported response. Verified locally against XRPL Testnet (xrpl:1) with funded faucet accounts: pnpm test --testnet --families=xrpl --versions=2 passes all 10 scenarios (axios/fetch x express/fastify/hono/next incl. withX402). * feat(examples): add XRPL to the advanced all_networks examples Registers @x402/xrpl in the client, server, and facilitator all_networks examples (alphabetical by network prefix), with XRPL_SEED/XRPL_ADDRESS/XRPL_NETWORK/XRPL_WS_URL configuration. * docs(examples): add XRPL setup to the advanced example READMEs Document the XRPL environment variables, testnet faucet steps, and reserve/trust line requirements in the advanced client, server, and facilitator example READMEs, and add the matching .env-local entries. The facilitator README also notes the keyless XRPL scheme (enabled via XRPL_NETWORK), its /supported kind with areFeesSponsored=false, and the xrpl:0 / xrpl:1 network identifiers. * fix(typescript): regenerate pnpm-lock.yaml after rebase onto main The website deprecation (#2794) removed the jiti-suffixed peer-dependency variants that the @x402/xrpl importer entries resolved to. Re-resolve the lockfile against the current workspace so frozen installs succeed. * fix(xrpl): bind signatures to account authorization and harden verification - Verify the embedded SigningPubKey is authorized for Account (master key pair unless disabled, or the configured regular key) via a validated account_info lookup. Offline signature validation only proves the blob was signed by its embedded key, and simulation strips signature fields, so an unauthorized signer previously passed /verify and failed at /settle with tefBAD_AUTH or tefMASTER_DISABLED. - Reject single-signed blobs that carry a Signers array; the single signature does not cover Signers, so hybrid blobs still pass verifySignature. - Fail closed on malformed extra.destinationTag in the facilitator, resource server, and client instead of silently skipping the tx-level binding. - Correct the changeset wording: the server scheme passes through configured invoice ids, it does not generate them. - Cover the new checks and previously untested spec rules in unit tests: envelope mismatches, NetworkID branches, XRP/IOU amount and SendMax variants, LastLedgerSequence bounds, InvoiceID mismatch, sequence 0, settle outcomes, and client-side NetworkID handling. * test(xrpl): add env-gated live settlement integration test Mirror the NEAR exact-near.live.test.ts pattern: when XRPL_PAYER_SEED and XRPL_LIVE_PAYTO (or the e2e CLIENT_XRPL_SEED / SERVER_XRPL_ADDRESS names) are set, drive the reference client, resource server, and keyless facilitator end to end against a real network and assert the payTo XRP balance increases by exactly the requested drops. Skipped when the accounts are not configured, so it stays inert in CI. Verified against XRPL Testnet: settled tx 6AF0A4F630F2B43CA44544D5246B58260A01860A3CCBB331625229CD78696791. * fix(xrpl): mirror rippled signer-key ordering and require canonical signing keys - Authorize the configured regular key before the master-disabled check, matching rippled's fixMasterKeyAsRegularKey ordering so legacy accounts whose RegularKey equals their own address are not wrongly rejected. - Reject non-canonical SigningPubKey encodings (only 33-byte compressed secp256k1 or ed25519 keys) before signature validation; rippled refuses such keys at preflight, so accepting them would let verification pass for a transaction that can never settle. * feat(xrpl): create tickets automatically for ticketSequence payments When a ticketSequence payment finds no available ticket, the client now creates tickets through the ClientXrplSigner abstraction instead of throwing and requiring a manual createTickets() call. The new ticketCreateCount option controls the policy: it defaults to 1, allows up to 250 tickets per TicketCreate, and 0 restores the previous fail-fast behavior for pre-provisioned setups. Available tickets are still reused first and skip the creation transaction entirely. - Widen ClientXrplSigner.sign from Payment to SubmittableTransaction so the same signer can sign TicketCreate; createTickets accepts the signer abstraction instead of an xrpl.js Wallet. - Cover the default, configured, and disabled policies plus invalid counts in unit tests. * fix(xrpl): return a stable reason code for unexpected verification failures The verify() catch-all embedded the raw error message in the invalidReason string (invalid_exact_xrpl_payload_malformed: <message>), so integrators could not match on a stable code. Return invalid_exact_xrpl_facilitator_error and carry the raw diagnostic text separately in invalidMessage. Settlement submission errors keep the existing transaction_failed: <diagnostic> reason. * fix(xrpl): fail closed on missing or invalid IOU issuers Issued-currency requirements and accepted payloads must both carry a valid classic issuer address before the issuer comparison runs. Two absent issuers previously compared equal and passed envelope validation, and a single absent issuer surfaced as a confusing mismatch. Missing or malformed issuers now return invalid_exact_xrpl_iou_issuer_missing. * fix(xrpl): set the custom-network NetworkID when building payments The client validated that prepared transactions carried the correct NetworkID on custom networks (id > 1024) but relied on the preparer to add the field. Insert it while building the payment so the default and custom preparers both start from a correct transaction; validation still rejects preparers that remove or replace it. * refactor(xrpl): reuse parseMoneyString from @x402/core Replace the server scheme's hand-rolled money-string parsing with the shared parseMoneyString helper used by the other mechanism packages, aligning string-price edge-case handling with the rest of the SDK. * test(e2e): cover both XRPL asset-transfer methods on every server Replace the single /exact/xrpl route with explicit sequence and ticketSequence endpoints on Express, Fastify, Hono, and Next (both the proxy middleware and withX402), pinning extra.assetTransferMethod and the issuer for issued-currency pricing in each route config. Teach the harness that asset transfer methods are not EVM-only metadata: xrpl endpoints resolve their declared method and default to sequence, and the server proxy forwards the configured issuer. * test(e2e): add a self-managed XRPL Testnet IOU fixture pnpm xrpl:iou:setup creates or reuses dedicated Testnet issuer, payer, and payee accounts, funds missing ones through the faucet, enables DefaultRipple on the issuer, establishes the trust lines, and issues test USD to the payer, replenishing it on re-runs. Credentials are persisted only in the git-ignored e2e/.env with 0600 permissions, seeds are never logged, and the script refuses to run unless the connected ledger reports Testnet network id 1. Mask seed values alongside private keys in the harness debug output. * fix(xrpl): reject duplicate settlements with a settlement cache Concurrent /settle calls carrying the same signed blob each passed verification, and because XRPL submission is idempotent on the transaction hash, submitAndWait resolved the same validated tesSUCCESS for every caller. The facilitator therefore returned success to all of them, letting a client access the resource N times while paying once. Add an in-memory SettlementCache (mirroring the SVM one) keyed on the signed transaction hash. settle() checks and inserts the key synchronously between re-verification and submission, so concurrent duplicates are serialized: the first proceeds, the rest return a duplicate_settlement error. Unlike Solana's protocol-fixed blockhash lifetime, an XRPL transaction stays landable until its LastLedgerSequence, which the scheme derives from maxTimeoutSeconds. Each entry's retention is sized to that window (plus a margin) rather than a flat interval, so an entry cannot be evicted while a slow-to-validate duplicate could still pass re-verification. Document the mitigation as REQUIRED in the spec, including the per-process scope and the shared-store requirement for horizontally scaled facilitators.
Follow-up to #2801, implementing the maintainer suggestion to add XRPL as an optional network on the x402.org testnet facilitator. Unlike the other optional networks, XRPL is gated on an explicit FACILITATOR_XRPL_ENABLED=true flag rather than a private key: in the XRPL exact scheme the payer signs the transaction and pays its fee, so the facilitator needs no key or funds — it only verifies and submits the pre-signed blob. An optional FACILITATOR_XRPL_TESTNET_WS_URL override is supported for deployments that prefer their own node over the default public testnet endpoint, mirroring the e2e facilitator's XRPL_WS_URL option.
* Update docs/sdk-features.md Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/sdk-features.md Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/schemes/exact.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor --------- Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
…2856) * docs: add XRPL to buyer quickstart, network lists, and facilitators Complements #2854 (XRPL Setup in exact.mdx + sdk-features tables) with the remaining pages, mirroring how NEAR was documented in #2771: - quickstart-for-buyers: install line, XRPL signer section, multi-scheme registration example, and the summary package list - schemes/overview: add XRPL to the network implementations sentence - network-and-token-support: add the xrpl:<networkId> CAIP-2 identifier - dev-tools/facilitators: list the T54 XRPL facilitator (mainnet and testnet), which previously appeared on the ecosystem page removed in #2794 * docs: add XRPL to the token support table The Token Support ecosystem table and its intro sentence stopped at Concordium; add the XRPL row (XRP or any issued currency, transferred via a payer-signed Payment transaction) alongside the CAIP-2 identifier added in the previous commit. * docs: add XRPL to the network support summary bullet The Summary list at the bottom of network-and-token-support.mdx parallels the intro sentence updated in the previous commit; bring it in line so both lists end with the same network set.
* Update docs/core-concepts/network-and-token-support.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/core-concepts/network-and-token-support.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor --------- Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
* SIWX configured-origin fix * py+go * updated docs
* harden channel storage * handle failures * few more fixes * go * py * fix fmt
* Update docs/advanced-concepts/lifecycle-hooks.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/advanced-concepts/lifecycle-hooks.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor --------- Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
#2884) * fix(evm): auto-wrap any eth_account BaseAccount, not just LocalAccount _wrap_if_local_account only checked isinstance(signer, LocalAccount), so third-party wallet-provider adapters that extend eth_account's abstract BaseAccount directly (e.g. Coinbase AgentKit's EvmWalletSigner, or any custom-custody signer) were passed through unwrapped instead of being wrapped in EthAccountSigner. Calling such a signer's sign_typed_data with x402's positional (domain, types, primary_type, message) convention then misassigns arguments against its eth_account-style keyword signature, raising a KeyError deep in eth_account.messages.encode_typed_data. Broaden the check to BaseAccount (LocalAccount's own parent class) in all three duplicated occurrences: exact, upto, and batch_settlement client schemes. Adds regression tests with a minimal BaseAccount-only signer. Reproduced against a real x402 v2 GatewayWalletBatched payment requirement signed by an AWS KMS-backed signer wrapped in a BaseAccount subclass. Note: most of this change was written with AI assistance (Claude Code) and reviewed/verified by me before submission, per this repo's AI-assisted contribution guidelines. * docs(changelog): add fragment for #2884
* feat(extensions): add code and cause to SIWx failure results * refactor(extensions): align SIWx validation result with verify response shape * remove cause, also align SIWxVerifyResult with facilitator verify --------- Co-authored-by: vraspar <v2parikh@uwaterloo.ca>
* Update docs/extensions/sign-in-with-x.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/extensions/sign-in-with-x.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/extensions/sign-in-with-x.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/extensions/sign-in-with-x.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor --------- Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
* py SIWX structured-error * go SIWX structured-error
The examples index was last updated in #345 (2025-08-18). The v2 restructure in #705 rewrote every example under examples/typescript but left it untouched: of its 20 entries, 13 point at directories that no longer exist, and 29 of the 35 examples on disk are missing. Rebuild all four listings from what is on disk, add indexes for fullstack/ and facilitator/, and correct claims that no longer hold: custom/ does not use @x402/core alone, and Fastify now has a package.
* limit s array size * go/py * add changeset * fix fmt
* Update docs/extensions/builder-code.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor * Update docs/extensions/builder-code.mdx Generated-By: mintlify-agent Mintlify-Source: dashboard-editor --------- Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
* fix(python): preserve streaming bodies on payment retry Buffer request content before the initial send so a 402 retry replays the same body. * chore(python): use pull request number for changelog
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Tests
Checklist